<template>
	<div class="display-inline-block upload">
		<el-upload action="" accept=".xlsx" :show-file-list="false" :http-request="(params: UploadRequestOptions) => uploadFile(params)">
			<slot>
				<el-button icon="Upload"> 导 入 </el-button>
			</slot>
		</el-upload>
		<el-dialog v-model="dialog.open" :title="dialog.title" width="1500px" append-to-body :close-on-click-modal="false" v-bind="dialogAttrs">
			<my-table :data="dialog.state.list" :columns="dialog.state.columns" max-height="500">
				<template #index="{ $index }">{{ $index + 1 }}</template>
				<template #desc="{ row }">
					<span class="text-#ff0000"> {{ row.desc }}</span>
				</template>
			</my-table>
		</el-dialog>
	</div>
</template>

<script setup name="MyButtonUpload" lang="ts">
import { UploadRequestOptions } from 'element-plus';

/***
 * <my-button-upload columns="[{ label: '序号', prop: 'index', width: 60, fixed: 'left' }, { label: '错误描述', prop: 'desc', width: 300, fixed: 'left' }]" parameter="{tempType:'JNData'}" uploadApi="postImportHd"/>
 * props
 * @property {String} accept 上传的文件格式，默认位'.xlsx'
 * @property {Array} columns 上传错误的表格columns，默认为[]
 * @property {Object} dialogAttrs 上传错误dialog弹窗的相关信息
 * @property {Object} parameter 上传文件的一些参数，按照对象的格式传递
 * @property {Function} preFn 文件上传前的组建参数时的前置函数，preFn="(上传文件的参数)=>{}"
 * @property {Function} [uploadApi] 文件上传的axios方法
 */
const props = defineProps({
		accept: {
			type: String,
			default: '.xlsx'
		},
		columns: {
			type: Array as PropType<columnsType[]>,
			default: () => []
		},
		dialogAttrs: {
			type: Object,
			default: () => {}
		},
		parameter: {
			type: Object,
			default: () => {}
		},
		preFn: {
			type: Function
		},
		uploadApi: {
			type: Function,
			required: true
		}
	}),
	/**
	 * 上传完成时的回调
	 */
	emit = defineEmits(['finally']);

const dialog = computed(() => ({
	title: '导入错误提示',
	open: false,
	state: {
		list: [],
		columns: props.columns
	}
}));

function uploadFile(params: UploadRequestOptions): XMLHttpRequest | Promise<unknown> {
	const _file = params.file;
	const formData = new FormData();
	formData.append('file', _file);
	for (const key in props.parameter) {
		if (Object.hasOwnProperty.call(props.parameter, key)) {
			formData.append(key, props.parameter[key]);
		}
	}
	props.preFn?.(formData);
	return props
		.uploadApi(formData)
		.then((res: any) => {
			if (res.data) {
				msgSuccess('导入成功');
			} else {
				msgError('导入失败');
				dialog.value.state.list = res.data?.errArr;
				dialog.value.open = true;
			}
		})
		.finally(() => {
			emit('finally');
		});
}
</script>

<style scoped>
.upload {
	margin: 0 12px;
	vertical-align: middle;
}
</style>
